package router

import (
	"FastDevelopGo/src/base/mess"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"runtime/debug"
	"strconv"
	"strings"
)

func InitRouter(r *gin.Engine) {
	//TODO 在这里我们进行初始化各种网关配置

	// 初始化默认静态资源
	r.StaticFS("/static", http.Dir("./static"))

	//TODO 初始化默认异常处理网关

	// 初始化默认模板目录
	r.LoadHTMLGlob("templates/*/**")

	// 加载404错误页面
	r.NoRoute(func(c *gin.Context) {
		// 实现内部重定向
		c.HTML(http.StatusOK, "error/404", gin.H{
			"title": "404",
		})
	})

	// 设置全部API接口的OPTION方式
	r.Use(Cors())

	// 设置500提示中间件
	r.Use(errorHttp)

	// 初始模板访问网关
	temRouter(r)

	// 测试网关
	testRouter(r)

	// 以下为本框架中的基础接口部分，可以根据选择进行去除或添加
	rg := r.Group("/api")
	loginRouter(rg)
}

// Cors 开放所有接口的OPTIONS方法
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method               //请求方法
		origin := c.Request.Header.Get("Origin") //请求头部
		var headerKeys []string                  // 声明请求头keys
		for k, _ := range c.Request.Header {
			headerKeys = append(headerKeys, k)
		}
		headerStr := strings.Join(headerKeys, ", ")
		if headerStr != "" {
			headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
		} else {
			headerStr = "access-control-allow-origin, access-control-allow-headers"
		}
		if origin != "" {
			origin := c.Request.Header.Get("Origin")
			c.Header("Access-Control-Allow-Origin", origin)                                    // 这是允许访问所有域
			c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
			//  header的类型
			c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
			//              允许跨域设置                                                                                                      可以返回其他子段
			c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
			c.Header("Access-Control-Max-Age", "172800")                                                                                                                                                           // 缓存请求信息 单位为秒
			c.Header("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域请求是否需要带cookie信息 默认设置为true
			c.Set("content-type", "application/json")                                                                                                                                                              // 设置返回格式是json
		}

		//放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.JSON(http.StatusOK, "Options Request!")
		}
		// 处理请求
		c.Next() //  处理请求
	}
}

func temRouter(r *gin.Engine) {
	// 统一404错误
	r.GET("/404", func(c *gin.Context) {
		c.HTML(http.StatusOK, "error/404", gin.H{
			"title": "404",
		})
	})
	// 首页面
	r.GET("/index", func(c *gin.Context) {
		c.HTML(200, "home/index", gin.H{
			"title": "Gin 测试模板",
		})
	})
	// 登录页面
	r.GET("/login", func(c *gin.Context) {
		c.HTML(http.StatusOK, "home/login", gin.H{
			"title": "用户登录",
		})
	})

}

// 测试网关
func testRouter(r *gin.Engine) {
	// 测试500中间件地址
	r.GET("/demo", func(c *gin.Context) {
		a := c.DefaultQuery("a", "1")
		i, _ := strconv.Atoi(a)
		// 当a参数是默认值1时会报错
		x := 0 / (1 - i)
		log.Println(x)
		c.JSON(http.StatusInternalServerError, fmt.Errorf("测试异常"))
	})

	// 测试-成功消息，常规赋值方式
	r.GET("/mess", func(c *gin.Context) {
		data := []string{
			"测试用户", "12岁", "男",
		}
		// 返回成功消息
		c.JSON(http.StatusOK, mess.ReturnReqMess("0", "成功", data))
	})
	// 测试-成功消息
	r.GET("/messOK", func(c *gin.Context) {
		data := []string{
			"测试用户002", "20岁", "女",
		}
		// 返回成功消息
		c.JSON(http.StatusOK, mess.ResMessOK(data))
	})
	// 测试-成功消息，常规赋值方式
	r.GET("/messErr", func(c *gin.Context) {
		// 返回成功消息
		c.JSON(http.StatusOK, mess.ResErrMess("1001011", "常规业务错误：", "用户名或密码错误"))
	})
}

// errorHttp 统一500错误处理函数
func errorHttp(c *gin.Context) {
	defer func() {
		if r := recover(); r != nil {
			// 打印错误堆栈信息
			log.Printf("panic: %v\n", r)
			debug.PrintStack()
			// 跳转错误页面
			c.HTML(200, "error/500", gin.H{
				"title": "500",
			})
		}
	}()
	//加载完 defer recover，继续后续接口调用
	c.Next()
}
